<template>
	<view class="main">
		<view class="flex-between" @click="openAll()">
			<view class="process-title">{{ title }}</view>
			<uni-icons
				v-if="title === '原有流程'"
				type="bottom"
				size="40rpx"
				color="#999999"
			></uni-icons>
		</view>
		<view
			v-show="isShowProcess"
			v-for="(item, inx) in progressArr"
			:key="item.taskId"
		>
			<view class="df pt40 root-name f28">
				<view
					:class="[
						inx === progressArr.length - 1
							? ''
							: `${
									item.finishTime
										? 'line-status'
										: 'dashed-line'
							  }`,
					]"
				></view>
				<view>
					<view v-if="item.user"
						><avatar
							:size="24"
							:fontsize="26"
							:width="80"
							:name="
								item.user.name && item.user.name.length > 2
									? item.user.name.slice(1)
									: item.user.name
							"
							:status="getStatus(item)"
						/>
					</view>
					<view v-else>
						<view v-if="item.nodeType === 'APPROVAL'">
							<view class="avatar-box avatar-box-color"
								><image
									:src="peoples"
									style="width: 60rpx; height: 60rpx"
								></image
							></view>
						</view>
						<view v-else class="avatar-box avatar-box-color"
							><image
								:src="promotion"
								style="width: 70rpx; height: 70rpx"
							></image
						></view>
					</view>
				</view>
				<view style="width: 85%" :class="'right-box' + inx">
					<view class="df jsb ml40">
						<view>
							<view class="g3 f28">{{ item.name }}</view>
							<view class="root-name f28">{{
								getDesc(item, inx)
							}}</view>
						</view>
						<view class="time g6 f28 tr">{{
							getShortTime(item.finishTime)
						}}</view>
					</view>
					<view
						v-if="item.users && item.users.length > 0"
						class="multi-user"
					>
						<view
							v-for="subItem in item.users"
							:key="subItem.taskId"
						>
							<view
								><avatar
									:status="getStatus(subItem)"
									:name="
										subItem.user.name &&
										subItem.user.name.length > 2
											? subItem.user.name.slice(1)
											: subItem.user.name
									"
									:size="22"
									:fontsize="22"
									:width="70"
									:left="48"
									:src="subItem.user.avatar"
								></avatar
							></view>
						</view>
					</view>
					<view
						v-show="item.comment && item.comment.length > 0"
						class="user-comment"
					>
						<view
							v-for="cmt in item.comment"
							:key="cmt.id"
							style="position: relative"
						>
							<view
								class="user-comment-user df ac ml40 mt20"
								v-if="item.users"
							>
								<view class="df ac">
									<avatar
										:size="24"
										:fontsize="24"
										:width="80"
										:name="cmt.user.name"
										:status="'comment'"
									></avatar>
									<text>（添加了评论）</text>
								</view>
								<view class="g6" v-if="item.users">{{
									getShortTime(cmt.createTime)
								}}</view>
							</view>
							<view
								class="mt20 ml40"
								v-if="
									item.result === 'add' &&
									cmt.orgUsers.length > 0
								"
							>
								添加审批人：{{
									cmt.orgUsers.length > 3
										? `${cmt.orgUsers[0].name}等${cmt.orgUsers.length}人`
										: cmt.orgUsers
												.map((i) => i.name)
												.join('、')
								}}
							</view>
							<view
								:class="
									['transfer', 'add'].includes(item.result) &&
									cmt.attachments &&
									cmt.attachments.length === 0 &&
									!cmt.text
										? ''
										: 'user-comment-content'
								"
							>
								<view class="text-comment f28 mt10">{{
									cmt.text ? cmt.text : ''
								}}</view>
								<view
									class="df mt20 mb20"
									v-show="cmt.signature"
								>
									<view>签名:</view>
									<image
										style="
											width: 200rpx;
											height: 200rpx;
											transform: rotate(90deg);
											margin-left: 20rpx;
										"
										:src="cmt.signature"
										mode="aspectFill"
										@tap="
											previewImage(
												cmt.signature,
												cmt.signature
											)
										"
									></image>
								</view>
								<view
									class="image-comment df flw mt10"
									v-show="
										cmt.attachments &&
										cmt.attachments.length > 0
									"
								>
									<image
										class="image mr20"
										:src="img"
										v-for="(img, i) in filterImages(
											cmt.attachments
										)"
										mode="aspectFill"
										:key="i"
										@tap="
											previewImage(cmt.attachments, img)
										"
									></image>
								</view>
								<view
									class="image-comment df flw mt10"
									v-show="
										cmt.attachments &&
										cmt.attachments.length > 0
									"
								>
									<view
										class="w100"
										v-for="(i, index) in filterAduio(
											cmt.attachments
										)"
										:key="index"
									>
										<diy-audio
											class="w80"
											:file="i.url"
											:audioTime="i.voiceDuration"
											:voiceText="i.voiceText"
										></diy-audio>
									</view>
								</view>
								<view class="file-comment mt10">
									<view
										class="word-warp df ac"
										@tap="previewFile(file)"
										style="color: #1989fa"
										v-for="file in filterFiles(
											cmt.attachments
										)"
										:key="file.id"
									>
										<view>
											<image
												src="@/static/img/attachment.png"
												mode="scaleToFill"
												style="
													width: 42rpx;
													height: 42rpx;
												"
											></image>
										</view>
										<view class="word-warp ml10">{{
											getNameByCenterDot(file.name)
										}}</view>
									</view>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import avatar from './avatar'
import diyAudio from '@/subPackagesIndex/components/diy-audio/diy-audio.vue'
import { previewFile, getNameByCenterDot } from '@/common/utils.js'
export default {
	components: { avatar, diyAudio },
	props: {
		progress: {
			type: Array,
			required: true,
			default: () => {
				return []
			},
		},
		processList: {
			type: Array,
			required: true,
			default: () => {
				return []
			},
		},
		result: {
			type: String,
			required: true,
			value: '',
			default: '',
		},
		title: {
			type: String,
			value: '',
			default: '',
		},
	},
	data() {
		return {
			getNameByCenterDot,
			peoples:
				'https://yilife-oss-dev-public.oss-cn-hangzhou.aliyuncs.com/34/130595/ORG/eqfppysuiukkqlk8mkd0b4nd2.png',
			promotion:
				'https://yilife-oss-online-public.oss-cn-hangzhou.aliyuncs.com/10000001/1015/ADMIN/g7aaul5jxwb6v3mx72bs83bml.png?timestamp=1676863638975',
			isShowProcess: true,
		}
	},
	methods: {
		// 预览文件
		previewFile(file) {
			const url = file.url
			previewFile(url)
		},
		//根据退回进行分段拆解
		splitByRecall(progress) {
			//提取分段时间点
			let points = progress
				.filter((p) => p.result === 'recall')
				.map((p) => new Date(p.startTime.replace(/-/g, '/')).getTime())
			if (points.length > 0) {
				let blocks = [] //分段流程块组
				let pointer = 0 //定点索引
				points.push(new Date().getTime())
				points.forEach((point) => {
					let block = []
					for (let i = pointer; i < progress.length; i++) {
						let startTime = new Date(
							progress[i].startTime.replace(/-/g, '/')
						).getTime()
						if (startTime <= point) {
							block.push(progress[i])
						} else {
							pointer = i
							break
						}
					}
					//存段
					blocks.push(block)
				})
				//按段处理
				let processNodes = []
				blocks.forEach((block) =>
					processNodes.push(...this.mergeTask(block))
				)
				return processNodes
			}
			return this.mergeTask(progress)
		},
		//合并活动节点，此处执行一段合并算法用来处理退回导致节点重合的问题
		mergeTask(progress) {
			let merge = []
			progress.forEach((pg) => {
				let i = merge.findIndex((n) => n.nodeId === pg.nodeId)
				if (i > -1) {
					//存在则合并到对象
					if (merge[i].users) {
						//已经合并过了
						merge[i].finishTime = pg.finishTime
						merge[i].users.push(pg)
						merge[i].result = this.getApprovalResult(
							merge[i],
							pg,
							pg.approvalMode
						)
						merge[i].comment = merge[i].comment.concat(pg.comment)
					} else {
						//没有就合并
						merge[i] = {
							agree: null,
							name: pg.name,
							nodeType: pg.nodeType,
							approvalMode: pg.approvalMode,
							nodeId: pg.nodeId,
							result: this.getApprovalResult(
								merge[i],
								pg,
								pg.approvalMode
							),
							startTime: merge[i].startTime,
							finishTime: pg.finishTime,
							comment: merge[i].comment.concat(pg.comment),
							users: [merge[i], pg],
						}
						// merge[i].comment = merge[i].comment.sort((a, b) => moment(a.createTime) - moment(b.createTime))
					}
				} else {
					merge.push(pg)
				}
			})
			return merge
		},

		getApprovalResult(oldVal, newVal, mode) {
			if (mode === 'OR') {
				return newVal.result ? newVal.result : oldVal.result
			} else if (mode === 'AND') {
				let rs = oldVal.result || newVal.result
				return rs === 'recall' ? 'recall' : rs
			} else {
				return newVal.result
			}
		},
		openAll() {
			this.isShowProcess = !this.isShowProcess
		},
		getShowProcess() {
			if (this.title === '原有流程') {
				this.isShowProcess = false
			} else {
				this.isShowProcess = true
			}
		},
		filterImages(attachments) {
			return (attachments || [])
				.filter((f) => f.isImage)
				.map((f) => {
					return this.getRes(f.url)
				})
		},
		getRes(url) {
			const reg = /^(http:|https:).*/gi
			return reg.test(url) ? url : this.RES_FILE_PRE + url
		},
		filterAduio(attachments) {
			return (attachments || [])
				.filter((f) => f.fileType == 2)
				.map((f) => {
					f.url = this.getRes(f.url)
					return f
				})
		},
		filterFiles(attachments) {
			return (attachments || [])
				.filter((f) => !f.isImage && f.fileType != 2)
				.map((f) => {
					f.url = this.getRes(f.url)
					return f
				})
		},
		getShortTime(time) {
			if (time) {
				return time.slice(0, 16).replaceAll('-', '.')
			}
			return ''
		},
		getStatus(item) {
			if (item.finishTime === null) {
				return 'pending'
			} else if (item.nodeType === 'CC') {
				return 'cc'
			} else if (item.result === 'agree') {
				return 'success'
			} else if (item.result === 'refuse') {
				return 'error'
			} else if (item.result === 'comment') {
				return 'comment'
			} else if (item.result === 'transfer') {
				return 'transfer'
			} else if (item.result === 'recall') {
				return 'recall'
			} else if (item.result === 'add') {
				return 'add'
			} else if (item.result === 'audit') {
				return 'audit'
			} else if (item.nodeType === 'cancel') {
				return 'cancel'
			} else {
				return undefined
			}
		},
		getDesc(item, index) {
			if (item.nodeType === 'ROOT') {
				if (item.result === 'cancel') {
					return `${
						item.user.name === uni.getStorageSync('loginUser').name
							? '我'
							: item.user.name
					}(撤销)`
				} else {
					return `${
						item.user.name === uni.getStorageSync('loginUser').name
							? '我'
							: item.user.name
					}`
				}
			} else if (
				item.nodeType === 'APPROVAL' ||
				item.nodeType === 'AUDIT'
			) {
				if (item.user) {
					return `${
						item.user.name === uni.getStorageSync('loginUser').name
							? '我'
							: item.user.name
					}${this.getAgree(item, index)}`
				}
				let desc = item.users.length
				switch (item.approvalMode) {
					case 'AND':
						return '同时审批（处理中）'
					case 'OR':
						return `${desc}人或签（处理中）`
					case 'NEXT':
						return '依次审批（处理中）'
				}
			} else if (item.nodeType === 'CC') {
				if (item.user) {
					return `抄送 ${
						item.user.name === uni.getStorageSync('loginUser').name
							? '我'
							: item.user.name
					}`
				}
				return `抄送 ${item.users.length}人`
			} else if (item.result === 'comment') {
				return `${
					item.user.name === uni.getStorageSync('loginUser').name
						? '我'
						: item.user.name
				}（添加了评论）`
			}
		},
		getAgree(item, index) {
			if (item.result === 'agree') {
				return '(已同意)'
			} else if (item.result === 'refuse') {
				return '(已拒绝)'
			} else if (item.result === 'audit') {
				return '(已办理)'
			} else if (item.result === 'recall') {
				const obj = this.progressArr[index + 1]
				return (
					'退回至 ' +
					`${obj.name}  ` +
					`${
						obj.users && obj.users.length > 0
							? obj.users[0].user.name +
							  '等' +
							  obj.users.length +
							  '人'
							: obj.user.name
					}`
				)
			}
			// else if (!item.result && item.finishTime) {
			// 	return '(已撤销)'
			// }
			else if (item.result === 'transfer') {
				return '(已转交)'
			} else if (item.result === 'add') {
				return '(加签)'
			} else {
				return '(处理中)'
			}
		},
		previewImage(urls, pic) {
			uni.previewImage({
				current: pic,
				urls: Array.isArray(urls) ? this.filterImages(urls) : [urls],
			})
		},
	},
	computed: {
		progressArr() {
			this.processList.forEach((item, index) => {
				if (
					(item.nodeType === 'APPROVAL' &&
						item.result &&
						item.result !== 'recall') ||
					(item.nodeType === 'ROOT' && item.result === 'cancel')
				) {
					item.nodeId = item.nodeId + index
				}
			})
			const list = this.splitByRecall(this.processList)
			list.forEach((i, inx) => {
				if (i.approvalMode === 'OR' && !i.result && i.finishTime) {
					list.splice(inx, 1)
				}
				if (i.result === 'recall' && i.users && i.users.length > 0) {
					const recallObj = i.users.find(
						(userItem) => userItem.result === 'recall'
					)
					list[inx] = {
						...recallObj,
					}
				}
			})
			return list
		},
		endStatus() {
			switch (this.result) {
				case null || '':
					return {
						text: '审批进行中',
						icon: 'icon-more1',
						color: '#b0b0b0',
					}
				case 'refuse-end':
					return {
						text: '审批被驳回',
						icon: 'icon-error',
						color: '#f56c6c',
					}
				case 'cancel-end':
					return {
						text: '审批被撤销',
						icon: 'icon-error',
						color: '#666',
					}
				default:
					return {
						text: '审批通过',
						icon: 'icon-success-filling',
						color: '#35b881',
					}
			}
		},
	},
	watch: {
		title(val) {
			if (val) {
				this.getShowProcess()
			}
		},
	},
}
</script>

<style scoped>
.process-title {
	color: #101010;
	font-weight: 700;
}
.user-comment-content {
	margin: 10rpx 10rpx 20rpx 40rpx;
	background: #eeeeee;
	padding: 10rpx;
	border-radius: 10rpx;
}
.image {
	width: 140rpx;
	height: 140rpx;
}
.multi-user {
	display: grid;
	margin-left: 40rpx;
	grid-template-columns: repeat(5, 55px);
	grid-row-gap: 15rpx;
	margin-top: 10rpx;
}
.avatar-box {
	color: #ffffff;
	text-align: center;
	font-size: 32rpx;
	width: 80rpx;
	height: 80rpx;
	display: flex;
	justify-content: center;
	align-items: center;
}
.avatar-box-color {
	background-color: #409eff;
	border-radius: 8rpx;
}
.status-color {
	background-color: #ccc;
}
.root-name {
	color: #9a9a9a;
}
.line-status {
	border: 3rpx solid #cecece;
	margin-top: 50rpx;
	position: relative;
	left: 40rpx;
	top: 35rpx;
}
.dashed-line {
	border: 3rpx dashed #cecece;
	margin-top: 50rpx;
	position: relative;
	left: 40rpx;
	top: 35rpx;
}
.main {
	padding: 32rpx 20rpx 32rpx 32rpx;
	background-color: #fff;
	font-size: 36rpx;
}
</style>
